package com.luhongzhe.gameview;

import java.util.Date;

import com.luhongzhe.Luhongzhe;
import com.luhongzhe.R;
import com.luhongzhe.tool.PathParser;
import com.luhongzhe.tool.PhysicalTool;

import data.ObjectDrawable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;

/**
 * @author 	luhongzhe
 * @email  	azhe0660@gmail.com
 * @date   	2011-11-1
 */

public class FallingBoxView extends CommonGameView
{
	private FallingBox mFallingBox;
	private ObjectDrawable car;
	private Bitmap bmpLand;
	
	public FallingBoxView(Context context, GameViewHolder holder)
	{
		super(context, holder);
	}
	
	@Override
	protected void drawGame(Canvas canvas)
	{
		mFallingBox.draw(canvas);
		canvas.drawBitmap(bmpLand, 0, 0, null);
	}
	
	@Override
	protected void onTouchDown(MotionEvent event)
	{
		super.onTouchDown(event);
        mFallingBox.hasCut = false;
	}
	
	@Override
	protected void onTouchMove(MotionEvent event)
	{
		float x = event.getX();
		float y = event.getY();
		if (!hasSucceed && mFallingBox.getBounds().contains((int)x, (int)y))
    	{
    		float rotation = (float)(Math.atan2(y - mY, x - mX) * 180 / Math.PI); 
    		Log.d(Luhongzhe.Tag, "rotation is " + rotation);
    		rotation = (rotation + 360) % 360;
    		if (rotation < 45 || rotation > 315)
    			rotation = 0;
    		else if (rotation >= 45 && rotation < 135)
    			rotation = 90;
    		else if (rotation >= 135 && rotation <= 225)
    			rotation = 180;
    		else rotation = 270;
    		Log.d(Luhongzhe.Tag, "rotation is " + rotation);
    		
    		mFallingBox.cut(rotation);
//    		onSucceed();
    		mX = x;
    		mY = y;
    	}
    	else
    	{
    		super.onTouchMove(event);
    	}
	}
	
	@Override
	protected void init()
	{
		mFallingBox = new FallingBox();
		
		car = new ObjectDrawable();
		car.setPath(PathParser.getCar(), 200, 200);
		
		bmpLand = BitmapFactory.decodeResource(getResources(), R.drawable.land);
		
		super.init();
	}
	
	class FallingBox extends Drawable
	{
		private int defaultSize = 50;
		
		private boolean hasCut;
		private long cutTime;
		private int cutX, cutY;
		private float hitRotation;
		
		private long beginTime;
		
		public FallingBox()
		{
			this.setBounds(0, 0, defaultSize, defaultSize);
			beginTime = new Date().getTime();
		}
		
		public void move(int x, int y)
		{
			this.setBounds(x, y, x + defaultSize, y + defaultSize);
		}
		
		public void cut(float hitRotation)
		{
			if (!hasCut)
			{
				hasCut = true;
				cutTime = getTime();
				this.cutX = this.getBounds().left;
				this.cutY = this.getBounds().top;
				this.hitRotation = hitRotation;
			}
		}
		
		@Override
		public void draw(Canvas canvas)
		{
			if (!hasCut)
			{
				int time = (int)getTime();
//				time %= gravityTool.getCycleTime();
				time %= PhysicalTool.getTime(FallingBoxView.this.getMeasuredHeight() + defaultSize * 2,
						0, PhysicalTool.gravityA);
				
//				int offset = (int)gravityTool.getOffset(time);
				int offset = (int)PhysicalTool.getFallingDistance(0, time);
				
				this.move(200, offset - mFallingBox.defaultSize);
				
				canvas.drawRect(this.getBounds(), defaultPaint);
			}
			else
			{
				this.setBounds(canvas.getClipBounds());
				int time = (int)(getTime() - cutTime);
				
				float hitAcceleration = 0.1f;
				
//				float hitRotation = 270;
				
				//child1
				float childHitRotation = hitRotation - 45;
				
				int offsetY = (int)PhysicalTool.getFallingDistance(hitAcceleration * (float)Math.sin(childHitRotation * Math.PI / 180) , time);
				int offsetX = (int)(time * hitAcceleration * Math.cos(childHitRotation * Math.PI / 180));
				Log.d("luhongzhe", "offsetY " + offsetY + "  offsetX " + offsetX);
				
				int clockwise = -1;
				float rotation = hitRotation + clockwise * (time * 90 / 1000) % 360;
				
				Rect bound = new Rect(cutX + offsetX, offsetY + cutY, cutX + offsetX + defaultSize, offsetY + cutY + defaultSize / 2);
				canvas.save();
				canvas.rotate(rotation, bound.centerX(), bound.centerY());
				canvas.drawRect(bound, defaultPaint);
				canvas.restore();
				
				//child2
				childHitRotation = hitRotation + 45;
				offsetX = (int)(time * hitAcceleration * Math.cos(childHitRotation * Math.PI / 180));
				offsetY = (int)PhysicalTool.getFallingDistance(hitAcceleration * (float)Math.sin(childHitRotation * Math.PI / 180) , time);
				
				clockwise = 1;
				rotation = hitRotation + clockwise * (time * 90 / 1000) % 360;
				
				bound = new Rect(cutX + offsetX, offsetY + cutY, cutX + offsetX + defaultSize, offsetY + cutY + defaultSize / 2);
				canvas.save();
				canvas.rotate(rotation, bound.centerX(), bound.centerY());
				canvas.drawRect(bound, defaultPaint);
				canvas.restore();
			}
		}

		@Override
		public void setAlpha(int alpha) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void setColorFilter(ColorFilter cf) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public int getOpacity() {
			// TODO Auto-generated method stub
			return 0;
		}
		
		private long getTime()
		{
			return new Date().getTime() - beginTime;
		}
		
	}

}
